
package com.example.jchuah.tiles;
import android.app.Activity;
import android.graphics.Color;
import android.inputmethodservice.Keyboard;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.GridLayout;
import android.widget.RelativeLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.GridLayout;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;

import java.util.Random;

public class MyActivity extends Activity implements View.OnTouchListener, View.OnDragListener {

    int numRows = 4;
    int numCols = 4;

    View[][] grid = new View[numRows][numCols];
    GridLayout gridview;

    Random randGen = new Random();

    GestureDetector.SimpleOnGestureListener simpleOnGestureListener = new GestureDetector.SimpleOnGestureListener(){
        @Override
        public boolean onDown(MotionEvent e){
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
            if(Math.abs(velocityX) > 3 || Math.abs(velocityY) > 3) {

                if (Math.abs(velocityX) > Math.abs(velocityY)) {

                    if (velocityX > 0) {

                        slideRight();
                    } else {

                        slideLeft();
                    }

                } else {
                    if (velocityY > 0) {
                        slideDown();
                    } else {
                        slideUp();

                    }
                }
            }
            return super.onFling(e1, e2, velocityX, velocityY);
        }
    };

    GestureDetector gestureDetector;

    View lastTouched = null;

    public void addTile(RowColPair pair, View tile) {
        addTile(pair.row, pair.col, tile);
    }

    public boolean isValidRowColPair(RowColPair pair) {
        return (pair.col >= 0 && pair.row >= 0 &&
                pair.row < grid.length && pair.col < grid[0].length);
    }

    public void slideLeft(){
        Log.d("fling event", "left");
        Animation slideLeft = AnimationUtils.loadAnimation(this, R.anim.animation_left);
        //lastTouched.startAnimation(slideLeft);
        RowColPair originalTile = getRowColumn(lastTouched);
        RowColPair newTile = originalTile.getLeft();



        if(isValidRowColPair(newTile)){
            View sourceTile = grid[originalTile.row][originalTile.col];
            if(!isEmpty(newTile)){
                View targetTile = grid[newTile.row][newTile.col];
                TextView sourceTileValue = (TextView)sourceTile.findViewById(R.id.value);
                TextView targetTileValue = (TextView)targetTile.findViewById(R.id.value);
                String sourceTileValueText = (String)sourceTileValue.getText();
                String targetTileValueText = (String)targetTileValue.getText();

                if(sourceTileValueText.equals(targetTileValueText)){
                    int sourceTileInt = Integer.parseInt(sourceTileValueText);
                    sourceTileInt = sourceTileInt * 2;
                    sourceTileValueText = Integer.toString(sourceTileInt);
                    sourceTileValue.setText(sourceTileValueText);
                    extractTile(newTile);
                    extractTile(originalTile);
                    addTile(newTile, sourceTile);


                }
            }else if(isEmpty(newTile)){
                extractTile(originalTile);
                addTile(newTile,sourceTile);

            }
        }
    }
    public void slideRight() {
        Log.d("fling event", "right");
        Animation slideRight = AnimationUtils.loadAnimation(this, R.anim.animation_right);
        //lastTouched.startAnimation(slideRight);
        RowColPair originalTile = getRowColumn(lastTouched);
        RowColPair newTile = originalTile.getRight();



        if (isValidRowColPair(newTile)) {
            View sourceTile = grid[originalTile.row][originalTile.col];
            if(!isEmpty(newTile)){

                View targetTile = grid[newTile.row][newTile.col];
                TextView sourceTileValue = (TextView)sourceTile.findViewById(R.id.value);
                TextView targetTileValue = (TextView)targetTile.findViewById(R.id.value);
                String sourceTileValueText = (String)sourceTileValue.getText();
                String targetTileValueText = (String)targetTileValue.getText();


                if (sourceTileValueText.equals(targetTileValueText)) {

                    int sourceTileInt = Integer.parseInt(sourceTileValueText);
                    sourceTileInt = sourceTileInt * 2;
                    sourceTileValueText = Integer.toString(sourceTileInt);
                    sourceTileValue.setText(sourceTileValueText);
                    extractTile(newTile);
                    extractTile(originalTile);
                    addTile(newTile, sourceTile);


                }
            }else if(isEmpty(newTile)){
                extractTile(originalTile);
                addTile(newTile,sourceTile);

            }
        }
    }
    public void slideDown() {
        Log.d("fling event", "down");
        Animation slideDown = AnimationUtils.loadAnimation(this, R.anim.animation_down);
        //lastTouched.startAnimation(slideDown);

        RowColPair originalTile = getRowColumn(lastTouched);
        RowColPair newTile = originalTile.getBelow();



        if(isValidRowColPair(newTile)){
            View sourceTile = grid[originalTile.row][originalTile.col];
            if(!isEmpty(newTile)){
                View targetTile = grid[newTile.row][newTile.col];
                TextView sourceTileValue = (TextView)sourceTile.findViewById(R.id.value);
                TextView targetTileValue = (TextView)targetTile.findViewById(R.id.value);
                String sourceTileValueText = (String)sourceTileValue.getText();
                String targetTileValueText = (String)targetTileValue.getText();

                if(sourceTileValueText.equals(targetTileValueText)){
                    int sourceTileInt = Integer.parseInt(sourceTileValueText);
                    sourceTileInt = sourceTileInt * 2;
                    sourceTileValueText = Integer.toString(sourceTileInt);
                    sourceTileValue.setText(sourceTileValueText);
                    extractTile(newTile);
                    extractTile(originalTile);
                    addTile(newTile, sourceTile);

                }
            }else if(isEmpty(newTile)){
                extractTile(originalTile);
                addTile(newTile,sourceTile);

            }
        }
    }
    public void slideUp() {
        Log.d("fling event", "up");
        Animation slideUp = AnimationUtils.loadAnimation(this, R.anim.animation_up);
        //lastTouched.startAnimation(slideUp);
        RowColPair originalTile = getRowColumn(lastTouched);
        RowColPair newTile = originalTile.getAbove();



        if (isValidRowColPair(newTile)) {
            View sourceTile = grid[originalTile.row][originalTile.col];
            if(!isEmpty(newTile)){
                View targetTile = grid[newTile.row][newTile.col];
                TextView sourceTileValue = (TextView) sourceTile.findViewById(R.id.value);
                TextView targetTileValue = (TextView) targetTile.findViewById(R.id.value);
                String sourceTileValueText = (String) sourceTileValue.getText();
                String targetTileValueText = (String) targetTileValue.getText();

                if (sourceTileValueText.equals(targetTileValueText)) {
                    int sourceTileInt = Integer.parseInt(sourceTileValueText);
                    sourceTileInt = sourceTileInt * 2;
                    sourceTileValueText = Integer.toString(sourceTileInt);
                    sourceTileValue.setText(sourceTileValueText);
                    extractTile(newTile);
                    extractTile(originalTile);
                    addTile(newTile, sourceTile);
                }
            } else if(isEmpty(newTile)){
                extractTile(originalTile);
                addTile(newTile,sourceTile);

            }
        }
    }

    public View extractTile(RowColPair pair) {
        View tile = grid[pair.row][pair.col];
        grid[pair.row][pair.col] = null;
        gridview.removeView(tile);
        return tile;

    }
    public void generateGrid() {
        for (int row = 0; row < numRows; row++){
            for (int col = 0; col < numCols; col++) {
                View tile = getLayoutInflater().inflate(R.layout.tile, null);


                tile.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                        TextView value = (TextView) view.findViewById(R.id.value);
                        RowColPair pair = getRowColumn(view);
                        //Toast.makeText(MyActivity.this,"You touched "+value.getText()+" At row "+ pair.row+" and Column " +
                        //        pair.col, Toast.LENGTH_SHORT).show();

                        lastTouched = view;
                        return gestureDetector.onTouchEvent(motionEvent);
                    }
                });
                TextView value = (TextView) tile.findViewById(R.id.value);



                int randomInt = randGen.nextInt(2) + 1;
                int newNumber = (int) Math.pow(2, randomInt);
                value.setText(newNumber + "");


                addTile(row, col, tile);

            }
        }
    }

    public void OnStartNewPush(View view) {
        Intent intent = new Intent(this, MyActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        startActivity(intent);
    }

    public void addTile(int row, int col, View tile) {
        GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
        layoutParams.rowSpec = GridLayout.spec(row);
        layoutParams.columnSpec = GridLayout.spec(col);
        tile.setLayoutParams(layoutParams);
        gridview.addView(tile);
        grid[row][col] = tile;
    }




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        gridview = (GridLayout)findViewById(R.id.gridView);
        generateGrid();
        gestureDetector = new GestureDetector(this, simpleOnGestureListener);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        return false;
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }

    public RowColPair getRowColumn(View view) {
        RowColPair result = new RowColPair();
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == view) {
                    result.row = i;
                    result.col = j;
                    return result;
                }
            }
        }
        return result;
    }
    public View getTileAT(RowColPair pair){
        return grid[pair.row][pair.col];
    }
    public boolean isEmpty(RowColPair pair){
        return grid[pair.row][pair.col] == null;
    }







    class RowColPair {
        int row = -1;
        int col = -1;
        public Object clone() {
            RowColPair theClone = new RowColPair();
            theClone.row = row;
            theClone.col = col;
            return theClone;
        }
        public RowColPair getBelow() {
            RowColPair result = new RowColPair();
            result.row = row + 1;
            result.col = col;
            return result;
        }

        public RowColPair getAbove() {
            RowColPair result = new RowColPair();
            result.row = row - 1;
            result.col = col;
            return result;
        }
        public RowColPair getLeft() {
            RowColPair result = new RowColPair();
            result.row = row;
            result.col = col - 1;
            return result;
        }
        public RowColPair getRight() {
            RowColPair result = new RowColPair();
            result.row = row;
            result.col = col + 1;
            return result;
        }
    }
}


//combine
